<?php

namespace App\Services;

use App\Models\MasterUser;
use App\Models\MasterUserRole;
use common\enum\CommonEnum;
use common\enum\MasterLogEnum;
use common\utils\RedisKeys;
use common\utils\SysCode;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Redis;

class AdminService
{
    //获得管理员信息
    public static function getAdminList($param, $page = 1, $pageSize = 20)
    {
        $MasterUserModel = new MasterUser();
        $MasterUserTab = $MasterUserModel->getTable();
        $adminUserRoleModel = new MasterUserRole();
        $adminUserRoleTab = $adminUserRoleModel->getTable();
        $select = [
            'a.id',
            'a.username',
            'a.truename',
            'a.part',
            'a.job',
            'r.id as role',
            'r.role as rolename',
            'a.loginip',
            'a.logintime',
            'a.status',
            'a.expire_time',
            'a.white_list'
        ];
        $query = $MasterUserModel->from($MasterUserTab . ' as a')
            ->select($select)
            ->leftJoin($adminUserRoleTab . ' as r', 'a.role', '=', 'r.id')
            ->where('status','!=',CommonEnum::DELETE);
        $operator = Auth::user();
        if ($operator['role'] != CommonEnum::ADMIN_ROLE_ID){
            $query->where(function ($query) use ($operator){
                $query->where('a.creator',$operator['id'])
                    ->orWhere('a.id',$operator['id']);
            });
        }
        if (!empty($param['username'])) {
            $username = $param['username'];
            $query->whereRaw("LOCATE(?,a.username) > 0", [$username]);
        }
        $res = get_page_data($query, $page, $pageSize);
        foreach ($res['list'] as &$item) {
            $item['status'] = (int)$item['status'];
            if (strtotime($item['expire_time']) < time() && !empty($item['expire_time'])) {
                $item['status'] = CommonEnum::DISABLE;
            }
        }
        self::nullToStr($res);
        return $res;
    }

    //新增管理员
    public static function addAdmin($param)
    {
        $param['salt'] = salt();
        $exist = MasterUser::where('username', '=', $param['username'])->first();
        if ($exist) {
            if ($exist['status'] == CommonEnum::DELETE){
                error_exit(SysCode::ADMIN_USER_DELETED);
            }else{
                error_exit(SysCode::ADMIN_USER_NAME_ALREADY_EXIT);
            }
        }
        $param['password'] = password_encrypt($param['password'], $param['salt']);
        $operator = Auth::user();
        $param['creator'] = $operator['id'];
        unset($param['password_confirmation']);
        $res['insert_id'] = MasterUser::insertGetId($param);
        MasterUserRole::where('id', '=', $param['role'])->increment('num', 1);
        if (!$res['insert_id']) {
            error_exit(SysCode::FAILED);
        } else {//添加管理员账号写入日志
            $remark = str_replace('{:name}', $param['username'], MasterLogEnum::REMARK['admin_add']);
            MasterLogService::writeMasterLog(MasterLogEnum::ADMIN_ADD, MasterLogEnum::SUCCESS, $remark);
        }
        return $res;
    }

    //编辑管理员
    public static function editAdmin($id, $param, $type = '')
    {
        $user = MasterUser::where('id', '=', $id)->first();
        if (!$user) {
            error_exit(SysCode::ADMIN_USER_NOT_EXIT);
        }
        if (isset($param['username'])) {
            $checkName = MasterUser::where('username', '=', $param['username'])->first();
            if ($checkName && $checkName['id'] != $id) {
                error_exit(SysCode::ADMIN_USER_NAME_ALREADY_EXIT);
            }
        }
        if (isset($param['role'])) {
            $role = MasterUserRole::where('id', '=', $param['role'])->first();
            if (!$role) {
                error_exit(SysCode::ROLE_NOT_EXIST);
            }
            if ($user['role'] != $param['role']) {
                MasterUserRole::where('id', '=', $user['role'])->decrement('num', 1);
                MasterUserRole::where('id', '=', $param['role'])->increment('num', 1);
            }
        }
        if (isset($param['password'])) {
            $param['salt'] = salt();
            $param['password'] = password_encrypt($param['password'], $param['salt']);
        }
        unset($param['password_confirmation']);
        if (!empty($param['status']) && strtotime($user['expire_time']) < time()) {
            error_exit(SysCode::ADMIN_EXPIRE_TIME_OUT);
        }
        self::kickAdminOut($id);
        $result = MasterUser::where('id', '=', $id)->update($param);
        if ($result) {
            if ($type == 'status') {//启停写入日志
                $remark = str_replace(['{:type}', '{:name}'], [MasterLogEnum::START_AND_STOP[$param['status']], $user['username']], MasterLogEnum::REMARK['admin_start_and_stop']);
                MasterLogService::writeMasterLog(MasterLogEnum::ADMIN_START_AND_STOP, MasterLogEnum::SUCCESS, $remark);
            } elseif ($type == 'info') {//编辑写入日志
                self::adminEditLog($user, $param);
            } elseif ($type == 'password') {
                $remark = str_replace('{:name}', $user['username'], MasterLogEnum::REMARK['admin_edit_pwd']);
                MasterLogService::writeMasterLog(MasterLogEnum::EDIT_PWD, MasterLogEnum::SUCCESS, $remark);
            }
        } else {
            error_exit(SysCode::FAILED);
        }
        return $result;
    }

    /**
     * 修改管理员账号写入日志
     * @param $user
     * @param $param
     */
    public static function adminEditLog($user, $param)
    {

        $user      = $user->toArray();
        $paramRole = MasterUserRole::where('id', '=', $param['role'])->first();
        $userRole  = MasterUserRole::where('id', '=', $user['role'])->first();
        $data      = [
            'old' => [
                MasterLogEnum::ADMIN_EDIT_ARRAY['name']        => !empty($user['username']) ? $user['username'] : '',
                MasterLogEnum::ADMIN_EDIT_ARRAY['part']        => !empty($user['part']) ? $user['part'] : '',
                MasterLogEnum::ADMIN_EDIT_ARRAY['job']         => !empty($user['job']) ? $user['job'] : '',
                MasterLogEnum::ADMIN_EDIT_ARRAY['expire_time'] => !empty($user['expire_time']) ? $user['expire_time'] : '',
                MasterLogEnum::ADMIN_EDIT_ARRAY['role']        => !empty($userRole['role']) ? $userRole['role'] : '',
            ],
            'new' => [
                MasterLogEnum::ADMIN_EDIT_ARRAY['name']        => !empty($param['username']) ? $param['username'] : '',
                MasterLogEnum::ADMIN_EDIT_ARRAY['part']        => !empty($param['part']) ? $param['part'] : '',
                MasterLogEnum::ADMIN_EDIT_ARRAY['job']         => !empty($param['job']) ? $param['job'] : '',
                MasterLogEnum::ADMIN_EDIT_ARRAY['expire_time'] => !empty($param['expire_time']) ? $param['expire_time'] : '',
                MasterLogEnum::ADMIN_EDIT_ARRAY['role']        => !empty($paramRole['role']) ? $paramRole['role'] : '',
            ],
        ];
        $remark    = str_replace('{:name}', $user['username'], MasterLogEnum::REMARK['admin_edit']);
        MasterLogService::writeMasterLog(MasterLogEnum::ADMIN_EDIT, MasterLogEnum::SUCCESS, $remark, $data);
    }

    //删除管理员
    public static function delAdmin($id)
    {
        $user = MasterUser::where('id', '=', $id)->first();
        if (!$user) {
            error_exit(SysCode::ADMIN_USER_NOT_EXIT);
        }
        if ($user['num']) {
            error_exit(SysCode::ROLE_IN_USE);
        }
        MasterUserRole::where('id', '=', $user['role'])->decrement('num', 1);
        self::kickAdminOut($id);
        $result = MasterUser::where(['id' => $id])->update(['status' => CommonEnum::DELETE]);
        if (!$result) {
            error_exit(SysCode::FAILED);
        } else {//删除管理员账号写入日志
            $remark = str_replace('{:name}', $user['username'], MasterLogEnum::REMARK['admin_del']);
            MasterLogService::writeMasterLog(MasterLogEnum::ADMIN_DEL, MasterLogEnum::SUCCESS, $remark);
        }
        return $result;
    }

    //为空字段转为str类型
    private static function nullToStr(&$array)
    {
        if (is_array($array)) {
            foreach ($array as &$value) {
                if (is_array($value)) {
                    self::nullToStr($value);
                }
                if ($value === null) {
                    $value = '';
                }
            }
        }
    }

    //踢线管理员
    public static function kickAdminOut($adminId,$ttl = 3600*24)
    {
        if (is_array($adminId)){
            foreach ($adminId as $admin) {
                self::kickAdminOut($admin);
            }
        }else{
            $redis = Redis::connection();
            $key = RedisKeys::KICK_ADMIN.$adminId;
            $redis->setex($key,$ttl,CommonEnum::ENABLED);
        }
    }

    /**
     * 修改密码
     * @param $arrayData
     * @return mixed
     * @throws \App\Exceptions\CustomException
     */
    public static function editPwd($arrayData)
    {
        $user = Auth::user();
        $old  = password_encrypt($arrayData['old'], $user['salt']);
        if ($old !== $user['password']) {
            error_exit(SysCode::USER_PWD_ERROR);
        }
        if ($arrayData['old'] === $arrayData['new']) {
            error_exit(SysCode::USER_PWD_AGREEMENT);
        }
        $salt     = salt();
        $password = password_encrypt($arrayData['new'], $salt);
        $result   = MasterUser::where(['id' => $user['id']])->update(['salt' => $salt, 'password' => $password]);
        if (!$result) {
            error_exit(SysCode::USER_PWD_AGREEMENT);
        }
        return $result;
    }
}